home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / dev / src / GLperf3.12-src.lha / GLperf / Tex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-18  |  34.2 KB  |  977 lines

  1. /*
  2.  * (c) Copyright 1995, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  * Permission to use, copy, modify, and distribute this software for
  5.  * any purpose and without fee is hereby granted, provided that the above
  6.  * copyright notice appear in all copies and that both the copyright notice
  7.  * and this permission notice appear in supporting documentation, and that
  8.  * the name of Silicon Graphics, Inc. not be used in advertising
  9.  * or publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.
  11.  *
  12.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  13.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  14.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  15.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  16.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  17.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  18.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  19.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  20.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  21.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  22.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  23.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  24.  *
  25.  * US Government Users Restricted Rights
  26.  * Use, duplication, or disclosure by the Government is subject to
  27.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  28.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  29.  * clause at DFARS 252.227-7013 and/or in similar or successor
  30.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  31.  * Unpublished-- rights reserved under the copyright laws of the
  32.  * United States.  Contractor/manufacturer is Silicon Graphics,
  33.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  34.  *
  35.  * Author: John Spitzer, SGI Applied Engineering
  36.  *
  37.  */
  38. #include <math.h>
  39. #include "Tex.h"
  40. #include "TexLoadX.h"
  41. #include "TexCopyX.h"
  42. #include "TexBindX.h"
  43.  
  44. #undef offset
  45. #define offset(v) offsetof(TexImage,v)
  46.  
  47. static InfoItem TexImageInfo[] = {
  48. #define INC_REASON INFO_ITEM_ARRAY
  49. #include "Tex.h"
  50. #undef INC_REASON
  51. };
  52. #include <malloc.h>
  53.  
  54. TexImagePtr new_TexImage()
  55. {
  56.     TexImagePtr this = (TexImagePtr)malloc(sizeof(TexImage));
  57.     ImagePtr thisImage = (ImagePtr)(&this->image_TexImage);
  58.     TransferMapPtr thisTransferMap = (TransferMapPtr)(&this->transfermap_TexImage);
  59.  
  60.     CheckMalloc(this);
  61.     new_Test((TestPtr)this);
  62.     new_Image(thisImage);
  63.     new_TransferMap(thisTransferMap);
  64.     SetDefaults((TestPtr)this, TexImageInfo);
  65.     this->testType = TexImageTest;
  66.     this->subImage = False;
  67.     this->subImageData = 0;
  68. #ifdef GL_EXT_subtexture
  69.     this->subTexture = False;
  70.     this->subTexData = 0;
  71. #endif
  72. #ifdef GL_EXT_copy_texture
  73.     this->copyTexData = 0;
  74. #endif
  75.     this->mipmapData = 0;
  76.     this->mipmapDimData = 0;
  77.     this->imageData = 0;
  78.     this->usecPixelPrint = " microseconds per texel with TexImage";
  79.     this->ratePixelPrint = " texels per second with TexImage";
  80.     this->usecPrint = " microseconds per texture image load";
  81.     this->ratePrint = " texture images loaded per second";
  82.     /* Set virtual functions */
  83.     this->SetState = TexImage__SetState;
  84.     this->delete = delete_TexImage;
  85.     this->Copy = TexImage__Copy;
  86.     this->Initialize = TexImage__Initialize;
  87.     this->Cleanup = TexImage__Cleanup;
  88.     this->SetExecuteFunc = TexImage__SetExecuteFunc;
  89.     this->PixelSize = TexImage__Size;
  90.     this->TimesRun = TexImage__TimesRun;
  91.     return this;
  92. }
  93.  
  94. void delete_TexImage(TestPtr thisTest)
  95. {
  96.     TexImagePtr this = (TexImagePtr)thisTest;
  97.     ImagePtr thisImage = (ImagePtr)(&this->image_TexImage);
  98.     TransferMapPtr thisTransferMap = (TransferMapPtr)(&this->transfermap_TexImage);
  99.  
  100.     delete_TransferMap(thisTransferMap);
  101.     delete_Image(thisImage);
  102.     delete_Test(thisTest);
  103. }
  104.  
  105. TestPtr TexImage__Copy(TestPtr thisTest)
  106. {
  107.     TexImagePtr this = (TexImagePtr)thisTest;
  108.     TexImagePtr newTexImage = new_TexImage();
  109.     FreeStrings((TestPtr)newTexImage);
  110.     *newTexImage = *this;
  111.     CopyStrings((TestPtr)newTexImage, (TestPtr)this);
  112.     return (TestPtr)newTexImage;
  113. }
  114.  
  115. static void* CreateSubExtentData(
  116.     int dim,
  117.     int width, int height, int depth, int extent,
  118.     int subwidth, int subheight, int subdepth, int subextent,
  119.     int drawOrder, int memAlignment, int* numDrawn)
  120. {
  121.     int reps[4];
  122.     int length[4];
  123.     int sublength[4];
  124.     float delta[4];
  125.     GLint* vals[4];
  126.     int stride, index;
  127.     int i, j;
  128.     GLint *subData, *subDataPtr;
  129.  
  130.     length[0] = width;   sublength[0] = subwidth;
  131.     length[1] = height;  sublength[1] = subheight;
  132.     length[2] = depth;   sublength[2] = subdepth;
  133.     length[3] = extent; sublength[3] = subextent;
  134.  
  135.     if (*numDrawn == 0) {
  136.     *numDrawn = 1;
  137.     for (i = 0; i < dim; i++) {
  138.         reps[i] = (int)ceil((float)length[i]/(float)sublength[i]);
  139.         *numDrawn *= reps[i];
  140.     }
  141.     } else {
  142.     int sideLen = (int)ceil(pow((float)(*numDrawn), 1./(float)dim));
  143.     for (i = 0; i < dim; i++)
  144.         reps[i] = sideLen;
  145.     }
  146.     for (i = dim; i < 4; i++)
  147.     reps[i] = 1;
  148.  
  149.     subData = (GLint*)AlignMalloc(sizeof(GLint) * dim * reps[0] * reps[1] * reps[2] * reps[3], memAlignment);
  150.     subDataPtr = subData;
  151.  
  152.     for (i = 0; i < dim; i++) {
  153.     delta[i] = (reps[i] == 1) ? 0. : (float)(length[i] - sublength[i]) / (float)(reps[i] - 1);
  154.     if (drawOrder == Spaced) {
  155.         for (j = reps[i]/2; j > 1; j--)
  156.         if (reps[i] % j) break;
  157.         if (j == 1)
  158.         drawOrder = Serial;
  159.         else
  160.         stride = j;
  161.     }
  162.     vals[i] = (GLint*)malloc(reps[i] * sizeof(GLint));
  163.     for (j = 0; j < reps[i]; j++) {
  164.         index = (drawOrder == Spaced) ? (j*stride%reps[i]) : j;
  165.         vals[i][j] = (GLint)floor((float)index * delta[i] + .5);
  166.     }
  167.     }
  168.     
  169.     /* This loop looks pretty bizarre, but it allows us to take a Cartesian
  170.      * product of the values in the vals array and get all combinations along
  171.      * each dimension
  172.      */
  173.     for (i = 0; i < *numDrawn; i++) {
  174.     *subDataPtr++ = vals[0][i % reps[0]];
  175.     if (dim > 1) *subDataPtr++ = vals[1][i / reps[0] % reps[1]];
  176.     if (dim > 2) *subDataPtr++ = vals[2][i / (reps[0] * reps[1]) % reps[2]];
  177.     if (dim > 3) *subDataPtr++ = vals[3][i / (reps[0] * reps[1] * reps[2]) % reps[3]];
  178.     }
  179.  
  180.     for (i = 0; i < dim; i++) free(vals[i]);
  181.  
  182.     return subData;
  183. }
  184.  
  185. static void DrawTriangle(TexImagePtr this)
  186. {
  187.     glBegin(GL_TRIANGLE_STRIP);
  188.     glTexCoord4f(.5, .5, 0., 1.);
  189.     glVertex3f(0., 0., -1.);
  190.     glTexCoord4f(.5 + 1./this->texImageWidth, .5, 0., 1.);
  191.     glVertex3f(2./this->environ.windowWidth, 0., -1.);
  192.     glTexCoord4f(.5, .5 + 1./this->texImageHeight, 0., 1.);
  193.     glVertex3f(0., 2./this->environ.windowHeight, -1.);
  194.     glEnd();
  195.     glFinish();
  196. }
  197.  
  198. void TexImage__Initialize(TestPtr thisTest)
  199. {
  200.     TexImagePtr this = (TexImagePtr)thisTest;
  201.     GLint *intTraversalData;
  202.     GLint *srcPtr;
  203.     GLfloat *dstPtr;
  204.     int i, j;
  205.     int   windowDim   = min(this->environ.windowWidth, this->environ.windowHeight);
  206.  
  207.     switch (this->texImageSrc) {
  208.     case SystemMemory:
  209.         this->numDrawn = 0;
  210.         if (this->subImage) {
  211. #ifdef GL_EXT_subtexture
  212.             if (this->subTexture) {
  213.                 this->subImageData = CreateSubExtentData(this->texDim,
  214.                                      this->image_TexImage.imageWidth,
  215.                                      this->image_TexImage.imageHeight,
  216.                                      this->imageDepth,
  217.                                      this->imageExtent,
  218.                                      this->subTexWidth, this->subTexHeight,
  219.                                      this->subTexDepth, this->subTexExtent,
  220.                                      this->drawOrder, this->memAlignment, &this->numDrawn);                
  221.         this->subTexData = CreateSubExtentData(this->texDim,
  222.                                      this->texImageWidth, this->texImageHeight,
  223.                                      this->texImageDepth, this->texImageExtent,
  224.                                      this->subTexWidth, this->subTexHeight,
  225.                                      this->subTexDepth, this->subTexExtent,
  226.                                      this->drawOrder, this->memAlignment, &this->numDrawn);
  227.         DefineTexImage(this->texTarget, this->texLevel, this->texComps,
  228.                                this->texImageWidth, this->texImageHeight,
  229.                                this->texImageDepth, this->texImageExtent,
  230.                                this->texBorder, this->image_TexImage.imageFormat,
  231.                                this->image_TexImage.imageType, (void*)0);
  232.             } else {
  233. #endif
  234.                 this->subImageData = CreateSubExtentData(this->texDim,
  235.                                      this->image_TexImage.imageWidth,
  236.                                      this->image_TexImage.imageHeight,
  237.                                      this->imageDepth,
  238.                                      this->imageExtent,
  239.                                      this->texImageWidth, this->texImageHeight,
  240.                                      this->texImageDepth, this->texImageExtent,
  241.                                      this->drawOrder, this->memAlignment, &this->numDrawn);
  242. #ifdef GL_EXT_subtexture
  243.             }
  244. #endif
  245.         } else {
  246. #ifdef GL_EXT_subtexture
  247.             if (this->subTexture) {
  248.                 this->subTexData = CreateSubExtentData(this->texDim,
  249.                                      this->texImageWidth, this->texImageHeight,
  250.                                      this->texImageDepth, this->texImageExtent,
  251.                                      this->subTexWidth, this->subTexHeight,
  252.                                      this->subTexDepth, this->subTexExtent,
  253.                                      this->drawOrder, this->memAlignment, &this->numDrawn);
  254.         DefineTexImage(this->texTarget, this->texLevel, this->texComps,
  255.                                this->texImageWidth, this->texImageHeight,
  256.                                this->texImageDepth, this->texImageExtent,
  257.                                this->texBorder, this->image_TexImage.imageFormat,
  258.                                this->image_TexImage.imageType, (void*)0);
  259.             } else {
  260. #endif
  261.                 this->numDrawn = 1;
  262. #ifdef GL_EXT_subtexture
  263.             }
  264. #endif
  265.         }
  266.         TexImage__CreateImageData(this);
  267.     break;
  268.     case DisplayList:
  269.     this->numDrawn = 1;
  270.         TexImage__CreateImageData(this);
  271.     if (this->texMipmap == PreCalculate) {
  272.         void*** mipmapData = this->mipmapData;
  273.         this->dlBase = glGenLists(this->numObjects);
  274.         for (i = 0; i < this->numObjects; i++) {
  275.         void** mipmap = *mipmapData;
  276.         GLint* mipmapDimPtr = this->mipmapDimData;
  277.         glNewList(this->dlBase+i, GL_COMPILE);
  278.         for (j = 0; j < this->mipmapLevels; j++) {
  279.             GLint width = *mipmapDimPtr++;
  280.             GLint height  = (this->texDim > 1) ? *mipmapDimPtr++ : 1;
  281.             GLint depth   = (this->texDim > 2) ? *mipmapDimPtr++ : 1;
  282.             GLint extent  = (this->texDim > 3) ? *mipmapDimPtr++ : 1;
  283.             DefineTexImage(this->texTarget, j, this->texComps, 
  284.                                width, height, depth, extent, 
  285.                                this->texBorder, this->image_TexImage.imageFormat, 
  286.                                this->image_TexImage.imageType, *mipmap++);
  287.         }
  288.         glEndList();
  289.         mipmapData++;
  290.         }
  291.     } else {
  292.         void** imageData = this->imageData;
  293.         this->dlBase = glGenLists(this->numObjects);
  294.         for (i = 0; i < this->numObjects; i++) {
  295.         glNewList(this->dlBase+i, GL_COMPILE);
  296.         DefineTexImage(this->texTarget, this->texLevel, this->texComps, 
  297.                                this->texImageWidth, this->texImageHeight, 
  298.                                this->texImageDepth, this->texImageExtent, 
  299.                                this->texBorder, this->image_TexImage.imageFormat,
  300.                                 this->image_TexImage.imageType, *imageData++);
  301.         glEndList();
  302.         }
  303.     }
  304.     break;
  305. #ifdef GL_EXT_copy_texture
  306.     case Framebuffer:
  307.         this->clearBefore = False;
  308.         Image__DrawSomething(this->environ.bufConfig.rgba, 
  309.                              this->environ.bufConfig.indexSize,
  310.                              this->environ.bufConfig.doubleBuffer);
  311.     this->numDrawn = 0;
  312.  #ifdef GL_EXT_subtexture
  313.     if (this->subTexture) {
  314.             this->copyTexData = CreateSubExtentData(2,
  315.                                      windowDim, windowDim, 1, 1,
  316.                                      this->subTexWidth, this->subTexHeight, 1, 1,
  317.                                      this->drawOrder, this->memAlignment, &this->numDrawn);
  318.             this->subTexData  = CreateSubExtentData(this->texDim,
  319.                                      this->texImageWidth, this->texImageHeight, this->texImageDepth, 1,
  320.                                      this->subTexWidth, this->subTexHeight, 1, 1,
  321.                                      this->drawOrder, this->memAlignment, &this->numDrawn);
  322.         DefineTexImage(this->texTarget, this->texLevel, this->texComps, 
  323.                                this->texImageWidth, this->texImageHeight, 
  324.                                this->texImageDepth, this->texImageExtent, 
  325.                                this->texBorder, this->image_TexImage.imageFormat, 
  326.                                this->image_TexImage.imageType, (void*)0);
  327.     } else {
  328.  #endif
  329.             this->copyTexData = CreateSubExtentData(2,
  330.                                      windowDim, windowDim, 1, 1,
  331.                                      this->texImageWidth, this->texImageHeight, 1, 1,
  332.                                      this->drawOrder, this->memAlignment, &this->numDrawn);
  333.  #ifdef GL_EXT_subtexture
  334.     }
  335.  #endif
  336. /*
  337.         TexImage__CreateImageData(this);
  338. */
  339.     break;
  340. #endif
  341. #ifdef GL_EXT_texture_object
  342.     case TexObj:
  343.     this->numDrawn = 1;
  344.         TexImage__CreateImageData(this);
  345.     this->texObjs = (GLuint*)malloc(this->numObjects * sizeof(GLuint));
  346.     CheckMalloc(this->texObjs);
  347.     glGenTexturesEXT(this->numObjects, this->texObjs);
  348.     if (this->texMipmap == PreCalculate) {
  349.         void*** mipmapData = this->mipmapData;
  350.         for (i = 0; i < this->numObjects; i++) {
  351.         void** mipmap = *mipmapData;
  352.         GLint* mipmapDimPtr = this->mipmapDimData;
  353.         glBindTextureEXT(this->texTarget, this->texObjs[i]);
  354.         glTexParameteri(this->texTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
  355.         glTexParameteri(this->texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  356.         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  357.         for (j = 0; j < this->mipmapLevels; j++) {
  358.             GLint width = *mipmapDimPtr++;
  359.             GLint height  = (this->texDim > 1) ? *mipmapDimPtr++ : 1;
  360.             GLint depth   = (this->texDim > 2) ? *mipmapDimPtr++ : 1;
  361.             GLint extent  = (this->texDim > 3) ? *mipmapDimPtr++ : 1;
  362.             DefineTexImage(this->texTarget, j, this->texComps, 
  363.                                width, height, depth, extent, 
  364.                                this->texBorder, this->image_TexImage.imageFormat, this->image_TexImage.imageType, *mipmap++);
  365.         }
  366.         mipmapData++;
  367.         DrawTriangle(this);
  368.         }
  369.     } else {
  370.         void** imageData = this->imageData;
  371.         for (i = 0; i < this->numObjects; i++) {
  372.         glBindTextureEXT(this->texTarget, this->texObjs[i]);
  373.         glTexParameteri(this->texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  374.         glTexParameteri(this->texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  375.         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  376.         DefineTexImage(this->texTarget, this->texLevel, this->texComps, 
  377.                                this->texImageWidth, this->texImageHeight, 
  378.                                this->texImageDepth, this->texImageExtent, 
  379.                                this->texBorder, this->image_TexImage.imageFormat, this->image_TexImage.imageType, *imageData++);
  380.         DrawTriangle(this);
  381.         }
  382.     }
  383.     /* Check for residence of the texture objects */
  384.     {
  385.         GLboolean *residence = (GLboolean*)malloc(this->numObjects * sizeof(GLboolean));
  386.         if (glAreTexturesResidentEXT(this->numObjects, this->texObjs, residence)) {
  387.         this->residentTexObjs = this->numObjects;
  388.         } else {
  389.         this->residentTexObjs = 0;
  390.         for (i = 0; i < this->numObjects; i++)
  391.             if (residence[i]) this->residentTexObjs++;
  392.         }
  393.         free(residence);
  394.     }
  395.     break;
  396. #endif
  397.     default:
  398.     break;
  399.     }
  400.     {
  401.     /* Define "point" - which is actually a triangle */
  402.     GLfloat *triPtr = this->triangleData = (GLfloat*)malloc(3 * (4 + 3) * sizeof(GLfloat));
  403.         *triPtr++ = .5; *triPtr++ = .5; *triPtr++ = 0.; *triPtr++ = 1.;
  404.         *triPtr++ = 0.; *triPtr++ = 0.; *triPtr++ = -1.;
  405.         *triPtr++ = .5 + 1./this->texImageWidth; *triPtr++ = .5; *triPtr++ = 0.; *triPtr++ = 1.;
  406.         *triPtr++ = 5./this->environ.windowWidth; *triPtr++ = 0.; *triPtr++ = -1.;
  407.         *triPtr++ = .5; *triPtr++ = .5 + 1./this->texImageHeight; *triPtr++ = 0.; *triPtr++ = 1.;
  408.         *triPtr++ = 0.; *triPtr++ = 5./this->environ.windowHeight; *triPtr++ = -1.;
  409.     }
  410. }
  411.  
  412. void TexImage__Cleanup(TestPtr thisTest)
  413. {
  414.     TexImagePtr this = (TexImagePtr)thisTest;
  415.     int i, j;
  416.  
  417.     if (this->subImageData) AlignFree(this->subImageData);
  418. #ifdef GL_EXT_subtexture
  419.     if (this->subTexData) AlignFree(this->subTexData);
  420. #endif
  421. #ifdef GL_EXT_copy_texture
  422.     if (this->copyTexData) AlignFree(this->copyTexData);
  423. #endif
  424.     if (this->mipmapData) {
  425.     void*** mipmapData = this->mipmapData;
  426.         for (i = 0; i < this->numObjects; i++) {
  427.         void** mipmap = *mipmapData;
  428.         for (j = 0; j < this->mipmapLevels; j++) {
  429.         AlignFree(*mipmap++);
  430.         }
  431.         free(*mipmapData++);
  432.     }
  433.     free(this->mipmapData);
  434.     }
  435.     if (this->mipmapDimData) AlignFree(this->mipmapDimData);
  436.     if (this->imageData) {
  437.     void **imageDataPtr = this->imageData;
  438.         for (i = 0; i < this->numObjects; i++) AlignFree(*imageDataPtr++);
  439.     free(this->imageData);
  440.     }
  441.  
  442.     switch (this->texImageSrc) {
  443.     case DisplayList:
  444.     if (glIsList(this->dlBase)) {
  445.         glDeleteLists(this->dlBase, this->numObjects);
  446.     }
  447.     break;
  448. #ifdef GL_EXT_texture_object
  449.     case TexObj:
  450.     if (this->texObjs) {
  451.         if (glIsTextureEXT(*this->texObjs))
  452.             glDeleteTexturesEXT(this->numObjects, this->texObjs);
  453.         free(this->texObjs);
  454.     }
  455.     break;
  456. #endif
  457.     default:
  458.     break;
  459.     }
  460.     free(this->triangleData);
  461. }
  462.  
  463. int TexImage__SetState(TestPtr thisTest)
  464. {
  465.     TexImagePtr this = (TexImagePtr)thisTest;
  466.     ImagePtr thisImage = (ImagePtr)(&this->image_TexImage);
  467.     TransferMapPtr thisTransferMap = (TransferMapPtr)(&this->transfermap_TexImage);
  468.  
  469.     int   windowDim   = min(this->environ.windowWidth, this->environ.windowHeight);
  470.     int noborderW;
  471.  
  472.     /* Initial parameter setting and checking */
  473.  
  474.     /* Source image is imageWidth by imageHeight,
  475.      * Texture image is texImageWidth by texImageHeight
  476.      * Subtexture image (if supported) is subTexWidth by subTexHeight
  477.      */
  478.     if (this->texImageWidth != -1) {
  479.     this->subImage = True;
  480.     } else {
  481.     this->texImageWidth = this->image_TexImage.imageWidth;
  482.     }
  483.     if (this->texImageHeight != -1) {
  484.     this->subImage = True;
  485.     } else {
  486.     this->texImageHeight = this->image_TexImage.imageHeight;
  487.     }
  488. #ifdef GL_EXT_texture3D
  489.     if (this->texImageDepth != -1) {
  490.     this->subImage = True;
  491.     } else {
  492.     this->texImageDepth = this->imageDepth;
  493.     }
  494. #else
  495.     this->texImageDepth = 1;
  496. #endif
  497. #ifdef GL_SGIS_texture4D
  498.     if (this->texImageExtent != -1) {
  499.     this->subImage = True;
  500.     } else {
  501.     this->texImageExtent = this->imageExtent;
  502.     }
  503. #else
  504.     this->texImageExtent = 1;
  505. #endif
  506.  
  507.     /* Clamp texImage dimensions to "parent" image if not copytexture */
  508.     if (this->texImageSrc != Framebuffer) {
  509.         if (this->texImageWidth > this->image_TexImage.imageWidth)
  510.         this->texImageWidth = this->image_TexImage.imageWidth;
  511.         if (this->texImageHeight > this->image_TexImage.imageHeight)
  512.         this->texImageHeight = this->image_TexImage.imageHeight;
  513. #ifdef GL_EXT_texture3D
  514.         if (this->texImageDepth > this->imageDepth)
  515.         this->texImageDepth = this->imageDepth;
  516. #endif
  517. #ifdef GL_SGIS_texture4D
  518.         if (this->texImageExtent > this->imageExtent)
  519.         this->texImageExtent = this->imageExtent;
  520. #endif
  521.     } else {
  522.     /* Clamp texImage dimensions to window if copytexture */
  523.         if (this->texImageWidth > windowDim)
  524.         this->texImageWidth = windowDim;
  525.         if (this->texImageHeight > windowDim)
  526.         this->texImageHeight = windowDim;
  527.     }
  528.  
  529.     /* Fill in dimensions that aren't defined (for reporting and possible use later */
  530.     /* when trying to generally figure the size of our images)                      */
  531.     switch (this->texTarget) {
  532.     case GL_TEXTURE_1D:
  533.     this->texImageHeight = 1;
  534.     case GL_TEXTURE_2D:
  535. #ifdef GL_SGIS_detail_texture
  536.     case GL_DETAIL_TEXTURE_2D_SGIS:
  537. #endif
  538. #ifdef GL_EXT_texture3D
  539.     this->texImageDepth = 1;
  540.     case GL_TEXTURE_3D_EXT:
  541. #endif
  542. #ifdef GL_SGIS_texture4D
  543.     this->texImageExtent = 1;
  544. #endif
  545.     default:
  546.     break;
  547.     }
  548.     switch (this->texTarget) {
  549.     case GL_TEXTURE_1D:
  550.     this->texDim = 1;
  551.     break;
  552.     case GL_TEXTURE_2D:
  553. #ifdef GL_SGIS_detail_texture
  554.     case GL_DETAIL_TEXTURE_2D_SGIS:
  555. #endif
  556.     this->texDim = 2;
  557.     break;
  558. #ifdef GL_EXT_texture3D
  559.     case GL_TEXTURE_3D_EXT:
  560.     this->texDim = 3;
  561.     break;
  562. #endif
  563. #ifdef GL_SGIS_texture4D
  564.     case GL_TEXTURE_4D_SGIS:
  565.     this->texDim = 4;
  566.     break;
  567. #endif
  568.     default:
  569.     break;
  570.     }
  571.  
  572.     /* Process subtexture if defined, else set subtexture dimensions to teximage dims */
  573. #ifdef GL_EXT_subtexture
  574.     if (this->subTexWidth != -1) {
  575.     this->subTexture = True;
  576.     } else {
  577.     this->subTexWidth = this->texImageWidth;
  578.     }
  579.     if (this->subTexHeight != -1) {
  580.     this->subTexture = True;
  581.     } else {
  582.     this->subTexHeight = this->texImageHeight;
  583.     }
  584.  #ifdef GL_EXT_texture3D
  585.     if (this->subTexDepth != -1) {
  586.     this->subTexture = True;
  587.     } else {
  588.     this->subTexDepth = this->texImageDepth;
  589.     }
  590.  #endif
  591.     this->subTexExtent = 1;
  592.     if (this->subTexWidth > this->texImageWidth)
  593.     this->subTexWidth = this->texImageWidth;
  594.     if (this->subTexHeight > this->texImageHeight)
  595.     this->subTexHeight = this->texImageHeight;
  596.  #ifdef GL_EXT_texture3D
  597.     if (this->subTexDepth > this->texImageDepth)
  598.     this->subTexDepth = this->texImageDepth;
  599.  #endif
  600. #endif
  601.  
  602.     /* Make sure everything's a power of two with the border removed */
  603.     noborderW = this->texImageWidth - this->texBorder * 2;
  604.     if (noborderW & noborderW - 1) return -1;
  605.     if (this->texTarget != GL_TEXTURE_1D) {
  606.     int noborderH = this->texImageHeight - this->texBorder * 2;
  607.         if (noborderH & noborderH - 1) return -1;
  608.     }
  609. #ifdef GL_EXT_texture3D
  610.     if (this->texTarget == GL_TEXTURE_3D_EXT) {
  611.     int noborderD = this->texImageDepth - this->texBorder * 2;
  612.         if (noborderD & noborderD - 1) return -1;
  613.     }
  614. #endif
  615. #ifdef GL_SGIS_texture4D
  616.     if (this->texTarget == GL_TEXTURE_4D_SGIS) {
  617.     int noborderD = this->texImageDepth - this->texBorder * 2;
  618.     int noborderV = this->texImageExtent - this->texBorder * 2;
  619.         if (noborderD & noborderD - 1 || noborderV & noborderV - 1) return -1;
  620.     }
  621. #endif
  622.  
  623. #ifdef GL_EXT_subtexture
  624.     this->subTexOrImage = this->subTexture || this->subImage;
  625. #else
  626.     this->subTexOrImage = this->subImage;
  627. #endif
  628.  
  629.     /* Can't have mipmap generation and subTexture/subImage simultaneously unless it's auto */
  630.     if (this->subTexOrImage && (this->texMipmap == PreCalculate || this->texMipmap == gluBuildMipmap) ||
  631.     /* No calls in GLU for mipmapping over 2 dimensional images */
  632.         this->texDim > 2 && this->texMipmap == gluBuildMipmap ||
  633. #ifdef GL_EXT_subtexture
  634.     /* No support in the SGIS_texture4d extension for subtexture */
  635.         this->texDim == 4 && this->subTexture ||
  636. #endif
  637. #ifdef GL_EXT_copy_texture
  638.     /* can't copy a 3D image from the framebuffer */
  639.         this->texDim == 3 && !this->subTexture && this->texImageSrc == Framebuffer ||
  640.     /* copy_texture extension doesn't support 4D textures */
  641.         this->texDim == 4 && this->texImageSrc == Framebuffer ||
  642. #endif
  643.     /* Mipmapping not supported at all in the SGIS_texture4d extension */
  644.         this->texDim == 4 && this->texMipmap != None)
  645.     return -1;
  646.     /* Can't support subTexture with DisplayList or TexObj because they're treated here as complete
  647.      * images (i.e. they're preloaded and only their swapping time is recorded) */
  648. #ifdef GL_EXT_texture_object
  649.     if ((this->subTexOrImage || this->texMipmap == gluBuildMipmap) && 
  650.         (this->texImageSrc == DisplayList || this->texImageSrc == TexObj))
  651.     return -1;
  652. #else
  653.     if ((this->subTexOrImage || this->texMipmap == gluBuildMipmap) && 
  654.          this->texImageSrc == DisplayList)
  655.     return -1;
  656. #endif
  657.  
  658.     /* set parent state */
  659.     if (Test__SetState(thisTest) == -1) return -1;
  660.  
  661.     /* set other inherited classes' states */
  662.     if (Image__SetState(thisImage) == -1) return -1;
  663.     if (TransferMap__SetState(thisTransferMap) == -1) return -1;
  664.  
  665.     /* set own state */
  666.     /* Make sure we won't be using any unsupported extensions! */
  667.     if (
  668.     this->texImageSrc == Framebuffer &&
  669.         !strstr(this->environ.glExtensions, "GL_EXT_copy_texture") ||
  670.         this->texImageSrc == TexObj &&
  671.         !strstr(this->environ.glExtensions, "GL_EXT_texture_object") ||
  672. #ifdef GL_SGIS_detail_texture
  673.         this->texTarget == GL_DETAIL_TEXTURE_2D_SGIS &&
  674.         !strstr(this->environ.glExtensions, "GL_SGIS_detail_texture") ||
  675. #endif
  676. #ifdef GL_EXT_texture3D
  677.         this->texTarget == GL_TEXTURE_3D_EXT &&
  678.         !strstr(this->environ.glExtensions, "GL_EXT_texture3D") ||
  679. #endif
  680. #ifdef GL_SGIS_texture4D
  681.         this->texTarget == GL_SGIS_texture4D &&
  682.         !strstr(this->environ.glExtensions, "GL_SGIS_texture4D") ||
  683. #endif
  684. #ifdef GL_EXT_subtexture
  685.     this->subTexture && 
  686.         !strstr(this->environ.glExtensions, "GL_EXT_subtexture") ||
  687. #endif
  688.     0) return -1;
  689.  
  690.     if (this->objDraw) {
  691.     GLfloat *triPtr;
  692.         /* set projection matrix */
  693.     glTexParameteri(this->texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  694.     glTexParameteri(this->texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  695.     glTexEnvi(this->texTarget, GL_TEXTURE_ENV_MODE, GL_DECAL);
  696.     glDisable(GL_DEPTH_TEST);
  697.     glDisable(GL_CULL_FACE);
  698.     glDrawBuffer(GL_FRONT);
  699.         glMatrixMode(GL_PROJECTION);
  700.         glLoadIdentity();
  701.         glOrtho(-1.0,1.0,-1.0,1.0,-0.5,1.5);
  702.         glMatrixMode(GL_TEXTURE);
  703.         glLoadIdentity();
  704.         glMatrixMode(GL_MODELVIEW);
  705.         glLoadIdentity();
  706.     glColor4f(1., 1., 1., 1.);
  707.     if (this->texDim == 1)
  708.         glEnable(GL_TEXTURE_1D);
  709.     else
  710.         glDisable(GL_TEXTURE_1D);
  711.     if (this->texDim == 2)
  712.         glEnable(GL_TEXTURE_2D);
  713.     else
  714.         glDisable(GL_TEXTURE_2D);
  715. #ifdef GL_EXT_texture3D
  716.     if (this->texDim == 3)
  717.         glEnable(GL_TEXTURE_3D_EXT);
  718.     else
  719.         glDisable(GL_TEXTURE_3D_EXT);
  720. #endif
  721. #ifdef GL_SGIS_texture4d
  722.     if (this->texDim == 4)
  723.         glEnable(GL_TEXTURE_4D_SGIS);
  724.     else
  725.         glDisable(GL_TEXTURE_4D_SGIS);
  726. #endif
  727.     }
  728.  
  729. #ifdef GL_SGIS_generate_mipmap
  730.  #ifdef GL_EXT_texture3d
  731.     if (this->texTarget == GL_TEXTURE_1D || 
  732.         this->texTarget == GL_TEXTURE_2D ||
  733.         this->texTarget == GL_TEXTURE_3D_EXT)
  734.  #else
  735.     if (this->texTarget == GL_TEXTURE_1D || this->texTarget == GL_TEXTURE_2D)
  736.  #endif
  737.         if (this->texMipmap == GenerateMipmapExt)
  738.         glTexParameteri(this->texTarget, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
  739.         else
  740.         glTexParameteri(this->texTarget, GL_GENERATE_MIPMAP_SGIS, GL_FALSE);
  741. #endif
  742.  
  743.     return 0;
  744. }
  745.  
  746. void TexImage__SetExecuteFunc(TestPtr thisTest)
  747. {
  748.     TexImagePtr this = (TexImagePtr)thisTest;
  749.     TexImageBindFunc bindfunc;
  750. #ifdef GL_EXT_copy_texture
  751.     TexImageCopyFunc copyfunc;
  752. #endif
  753.     TexImageLoadFunc loadfunc;
  754.  
  755.     switch (this->texImageSrc) {
  756. #ifdef GL_EXT_texture_object
  757.     case TexObj:
  758.         bindfunc.word = 0;
  759.         bindfunc.bits.texSrc = 1;
  760.         bindfunc.bits.objDraw = (this->objDraw == TexturedTriangle) 
  761.                                      ? 2 
  762.                                      : ((this->objDraw == TexturedPoint) ? 1 : 0);
  763.         bindfunc.bits.functionPtrs = this->loopFuncPtrs;
  764.         bindfunc.bits.multiimage = (this->numObjects > 1);
  765.         this->Execute = TexImageBindExecuteTable[bindfunc.word];
  766.         break;
  767. #endif
  768.     case DisplayList:
  769.         bindfunc.word = 0;
  770.         bindfunc.bits.texSrc = 0;
  771.         bindfunc.bits.objDraw = (this->objDraw == TexturedTriangle) 
  772.                                      ? 2 
  773.                                      : ((this->objDraw == TexturedPoint) ? 1 : 0);
  774.         bindfunc.bits.functionPtrs = this->loopFuncPtrs;
  775.         bindfunc.bits.multiimage = (this->numObjects > 1);
  776.         this->Execute = TexImageBindExecuteTable[bindfunc.word];
  777.         break;
  778. #ifdef GL_EXT_copy_texture
  779.     case Framebuffer:
  780.         copyfunc.word = 0;
  781.         copyfunc.bits.objDraw = (this->objDraw == TexturedTriangle) 
  782.                                      ? 2 
  783.                                      : ((this->objDraw == TexturedPoint) ? 1 : 0);
  784.         copyfunc.bits.functionPtrs = this->loopFuncPtrs;
  785.         copyfunc.bits.subtexture = this->subTexture;
  786.         copyfunc.bits.texDim = this->texDim - 1;
  787.         this->Execute = TexImageCopyExecuteTable[copyfunc.word];
  788.         break;
  789. #endif
  790.     case SystemMemory:
  791.         loadfunc.word = 0;
  792.         loadfunc.bits.objDraw = (this->objDraw == TexturedTriangle) 
  793.                                      ? 2 
  794.                                      : ((this->objDraw == TexturedPoint) ? 1 : 0);
  795.         loadfunc.bits.functionPtrs = this->loopFuncPtrs;
  796.         loadfunc.bits.subimage   = this->subImage;
  797. #ifdef GL_EXT_subtexture
  798.         loadfunc.bits.subtexture = this->subTexture;
  799. #endif
  800.         loadfunc.bits.texDim     = this->texDim - 1;
  801.         loadfunc.bits.multiimage = (this->numObjects > 1);
  802.         loadfunc.bits.multilevel = (this->texMipmap == PreCalculate);
  803.         loadfunc.bits.genMipmap  = (this->texMipmap == gluBuildMipmap);
  804.         this->Execute = TexImageLoadExecuteTable[loadfunc.word];
  805.         break;
  806.     }
  807. }
  808.  
  809. int TexImage__TimesRun(TestPtr thisTest)
  810. {
  811.     TexImagePtr this = (TexImagePtr)thisTest;
  812.     return this->numDrawn;
  813. }
  814.  
  815. float TexImage__Size(TestPtr thisTest)
  816. {
  817.     TexImagePtr this = (TexImagePtr)thisTest;
  818.     float size;
  819.     int texelsPerPixel = 1;
  820.  
  821. #ifdef GL_SGIS_texture_select
  822.     if (GL_DUAL_ALPHA4_SGIS <= this->texComps &&
  823.         this->texComps <= GL_DUAL_LUMINANCE_ALPHA8_SGIS) {
  824.         texelsPerPixel = 2;
  825.     } else if (GL_QUAD_ALPHA4_SGIS <= this->texComps &&
  826.         this->texComps <= GL_QUAD_INTENSITY8_SGIS) {
  827.         texelsPerPixel = 4;
  828.     }
  829. #endif
  830.  
  831. #ifdef GL_EXT_subtexture
  832.     if (this->subTexture)
  833.     size = this->subTexWidth * this->subTexHeight * 
  834.                this->subTexDepth * this->subTexExtent * texelsPerPixel;
  835.     else
  836. #endif
  837.     size = this->texImageWidth * this->texImageHeight * 
  838.                this->texImageDepth * this->texImageExtent * texelsPerPixel;
  839.     return (float)size;
  840. }
  841.  
  842. void TexImage__CreateImageData(TexImagePtr this)
  843. {
  844.     int i, j;
  845.     void **imagePtr;
  846.     int imageSize;
  847.     void *image;
  848.     int imageWidth, imageHeight;
  849.     int imageDepth = 1;
  850.     int imageExtent = 1;
  851.     int imageBorder;
  852.  
  853.     /* Figure out the dimensions of our base image and put them in imageWidth, etc. */
  854.     if (this->subTexOrImage) {
  855.     imageBorder = 0;
  856.     if (this->subImage) {
  857.         imageWidth = this->image_TexImage.imageWidth;
  858.         imageHeight = this->image_TexImage.imageHeight;
  859. #ifdef GL_EXT_texture3D
  860.         imageDepth = this->imageDepth;
  861. #endif
  862. #ifdef GL_SGIS_texture4D
  863.         imageExtent = this->imageExtent;
  864. #endif
  865.     } else { /* must be subTexture only */
  866. #ifdef GL_EXT_subtexture
  867.         imageWidth = this->subTexWidth;
  868.         imageHeight = this->subTexHeight;
  869. #ifdef GL_EXT_texture3D
  870.         imageDepth = this->subTexDepth;
  871. #endif
  872. #ifdef GL_SGIS_texture4D
  873.         imageExtent = 1; /* Subtexture not supported on 4D textures */
  874. #endif
  875. #endif
  876.     }
  877.     } else {
  878.     imageBorder = this->texBorder;
  879.     imageWidth = this->texImageWidth;
  880.     imageHeight = this->texImageHeight;
  881. #ifdef GL_EXT_texture3D
  882.     imageDepth = this->texImageDepth;
  883. #endif
  884. #ifdef GL_SGIS_texture4D
  885.     imageExtent = this->texImageExtent;
  886. #endif
  887.     }
  888.  
  889.     if (this->texMipmap == PreCalculate) {
  890.     int width, height, depth, extent;
  891.     const int maxLevels = 32; /* Be generous! */
  892.     int* mipmapSize = (int*)malloc(maxLevels * sizeof(int));
  893.         GLint* mipmapDimPtr;
  894.     void** mipmap = (void**)malloc(maxLevels * sizeof(void*));
  895.     void*** mipmapPtr;
  896.     int n = 0;
  897.     int realwidth, realheight, realdepth, realextent;
  898.     this->mipmapDimData = (GLint*)AlignMalloc(maxLevels * this->texDim * sizeof(GLint),
  899.                                                   this->memAlignment);
  900.     mipmapDimPtr = this->mipmapDimData;
  901.     /* Strip borders off image dimensions so figuring the mipmaps is easier */
  902.     imageWidth -= 2 * imageBorder;
  903.     if (this->texDim > 1)
  904.         imageHeight -= 2 * imageBorder;
  905. #ifdef GL_EXT_texture3D
  906.     if (this->texDim > 2)
  907.         imageDepth -= 2 * imageBorder;
  908. #endif
  909. #ifdef GL_SGIS_texture4D
  910.     if (this->texDim > 3)
  911.         imageExtent -= 2 * imageBorder;
  912. #endif
  913.     for (width = imageWidth, height = imageHeight, depth = imageDepth, extent = imageExtent;
  914.          width >= 1 || height >= 1 || depth >= 1 || extent >= 1;
  915.          width /= 2, height /= 2, depth /= 2, extent /= 2, n++) {
  916.         realwidth = max(width, 1);
  917.         realheight = max(height, 1);
  918.         realdepth = max(depth, 1);
  919.         realextent = max(extent, 1);
  920.         *mipmapDimPtr++ = realwidth = realwidth + 2 * imageBorder;
  921.         if (this->texDim > 1) *mipmapDimPtr++ = realheight = realheight + 2 * imageBorder;
  922.         if (this->texDim > 2) *mipmapDimPtr++ = realdepth = realdepth + 2 * imageBorder;
  923.         if (this->texDim > 3) *mipmapDimPtr++ = realextent = realextent + 2 * imageBorder;
  924.         mipmap[n] = MakeTexImage(realwidth,
  925.                      realheight,
  926.                      realdepth,
  927.                      realextent,
  928.                          this->image_TexImage.imageFormat,
  929.                          this->image_TexImage.imageType,
  930.                          this->image_TexImage.imageAlignment,
  931.                          this->image_TexImage.imageSwapBytes,
  932.                          this->image_TexImage.imageLSBFirst,
  933.                          this->memAlignment,
  934.                          &mipmapSize[n]);
  935.     }
  936.     /* Make numObjects copies of mipmaps and put them in mipmapData */
  937.     this->mipmapLevels = n;
  938.     this->mipmapData = (void***)malloc(sizeof(void**) * this->numObjects);
  939.     CheckMalloc(this->mipmapData);
  940.     mipmapPtr = this->mipmapData;
  941.     *mipmapPtr++ = mipmap;
  942.     for (i = 1; i < this->numObjects; i++) {
  943.         *mipmapPtr = (void**)malloc(this->mipmapLevels * sizeof(void*));
  944.         for (j = 0; j < this->mipmapLevels; j++) {
  945.         (*mipmapPtr)[j] = (void*)AlignMalloc(mipmapSize[j], this->memAlignment);
  946.         memcpy((*mipmapPtr)[j], mipmap[j], mipmapSize[j]);
  947.         }
  948.         mipmapPtr++;
  949.     }
  950.     free(mipmapSize);
  951.     } else {
  952.         image = MakeTexImage(imageWidth,
  953.              imageHeight,
  954.              imageDepth,
  955.              imageExtent,
  956.              this->image_TexImage.imageFormat,
  957.              this->image_TexImage.imageType,
  958.              this->image_TexImage.imageAlignment,
  959.              this->image_TexImage.imageSwapBytes,
  960.              this->image_TexImage.imageLSBFirst,
  961.              this->memAlignment,
  962.              &imageSize);
  963.  
  964.     /* Make numObjects copies of image and put them in imageData */
  965.         this->imageData = (void**)malloc(sizeof(void*) * this->numObjects);
  966.         CheckMalloc(this->imageData);
  967.         imagePtr = this->imageData;
  968.  
  969.         *imagePtr++ = image;
  970.         for (i = 1; i < this->numObjects; i++) {
  971.         *imagePtr = AlignMalloc(imageSize, this->memAlignment);
  972.         memcpy(*imagePtr, image, imageSize);
  973.         imagePtr++;
  974.         }
  975.     }
  976. }
  977.